home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 7 / BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso / Files / Art / P / PhotoShopDev.cpt / PhotoShopDev / Fil-Think C 4.0 / Dissolve.c next >
Text File  |  1990-02-13  |  8KB  |  427 lines

  1. /*
  2.     File: Dissolve.c
  3.  
  4.     Copyright 1990 by Thomas Knoll.
  5.  
  6.     Think C source file for Dissolve example.
  7. */
  8.  
  9. #include <MacTypes.h>
  10. #include <MemoryMgr.h>
  11. #include <ResourceMgr.h>
  12. #include <Quickdraw.h>
  13. #include <Color.h>
  14. #include <DialogMgr.h>
  15. #include <OSUtil.h>
  16. #include <PackageMgr.h>
  17. #include <SysErr.h>
  18. #include <ToolboxUtil.h>
  19. #include <pascal.h>
  20. #include <SetUpA4.h>
  21.  
  22. #include "FilterInterface.h"
  23.  
  24. #define nil 0L
  25. #define Length(string) (*(unsigned char *)(string))
  26.  
  27. typedef struct TParameters
  28.     {
  29.     short percent;
  30.     } TParameters, *PParameters, **HParameters;
  31.  
  32. short gResult;
  33. FilterRecordPtr gStuff;
  34.  
  35. /*****************************************************************************/
  36.  
  37. /* Calls the host's TestAbort function */
  38.  
  39. Boolean TestAbort (void)
  40.  
  41.     {
  42.     return CallPascalB (gStuff->abortProc);
  43.     }
  44.  
  45. /*****************************************************************************/
  46.  
  47. /* Calls the host's UpdateProgress procedure */
  48.  
  49. void UpdateProgress (done, total)
  50.  
  51. long done;
  52. long total;
  53.  
  54.     {
  55.     CallPascal (done, total, gStuff->progressProc);
  56.     }
  57.  
  58. /*****************************************************************************/
  59.  
  60. /* Centers a dialog template 1/3 of the way down on the main screen. */
  61.  
  62. void CenterDialog (dt)
  63.  
  64. DialogTHndl dt;
  65.  
  66. #define menuHeight 20
  67.  
  68.     {
  69.     Rect r;
  70.     short width;
  71.     short height;
  72.  
  73.     width  = screenBits.bounds.right;
  74.     height = screenBits.bounds.bottom;
  75.  
  76.     r = (**dt).boundsRect;
  77.     OffsetRect (&r, -r.left, -r.top);
  78.     OffsetRect (&r, (width - r.right) / 2,
  79.                     (height - r.bottom - menuHeight) / 3 + menuHeight);
  80.     (**dt).boundsRect = r;
  81.     }
  82.  
  83. #undef menuHeight
  84.  
  85. /*****************************************************************************/
  86.  
  87. /* Displays the about dialog box for the plug-in module. */
  88.  
  89. void DoAbout (void)
  90.  
  91. #define dialogID 16000
  92.  
  93.     {
  94.     short item;
  95.     DialogPtr dp;
  96.     DialogTHndl dt;
  97.  
  98.     dt = (DialogTHndl) GetResource ('DLOG', dialogID);
  99.     HNoPurge ((Handle) dt);
  100.     CenterDialog (dt);
  101.  
  102.     dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  103.  
  104.     ModalDialog (nil, &item);
  105.  
  106.     DisposDialog (dp);
  107.     HPurge ((Handle) dt);
  108.     }
  109.  
  110. #undef dialogID
  111.  
  112. /*****************************************************************************/
  113.  
  114. /* UserItem to outline the OK button in a dialog box. */
  115.  
  116. pascal void OutlineOK (dp, item)
  117.  
  118. DialogPtr dp;
  119. short item;
  120.  
  121.     {
  122.     Rect r;
  123.     Handle h;
  124.     short itemType;
  125.     
  126.     SetUpA4 ();
  127.  
  128.     item = OK;
  129.  
  130.     GetDItem (dp, item, &itemType, &h, &r);
  131.  
  132.     PenNormal ();
  133.     PenSize (3, 3);
  134.     
  135.     InsetRect (&r, -4, -4);
  136.     FrameRoundRect (&r, 16, 16);
  137.  
  138.     PenNormal ();
  139.     
  140.     RestoreA4 ();
  141.     }
  142.  
  143. /*****************************************************************************/
  144.  
  145. /* Asks the user for the plug-in filter module's parameters. Note that
  146.    the image size information is not yet defined at this point. Also, do
  147.    not assume that the calling program will call this routine every time the
  148.    filter is run (it may save the data held by the parameters handle in
  149.    a macro file). */
  150.  
  151. void DoParameters (void)
  152.  
  153. #define dialogID    16001
  154. #define hookItem    3
  155. #define percentItem 4
  156.  
  157.     {
  158.     Rect r;
  159.     long x;
  160.     short j;
  161.     Str255 s;
  162.     Handle h;
  163.     short item;
  164.     DialogPtr dp;
  165.     short itemType;
  166.     DialogTHndl dt;
  167.     Handle percentText;
  168.  
  169.     if (!gStuff->parameters)
  170.         {
  171.         gStuff->parameters = NewHandle (sizeof (TParameters));
  172.  
  173.         if (!gStuff->parameters)
  174.             {
  175.             gResult = memFullErr;
  176.             return;
  177.             }
  178.  
  179.         ((PParameters) *gStuff->parameters)->percent = 50;
  180.         }
  181.  
  182.     dt = (DialogTHndl) GetResource ('DLOG', dialogID);
  183.     HNoPurge ((Handle) dt);
  184.     CenterDialog (dt);
  185.  
  186.     dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  187.     
  188.     RememberA4 ();
  189.  
  190.     GetDItem (dp, hookItem, &itemType, &h                  , &r);
  191.     SetDItem (dp, hookItem,  itemType, (Handle) &OutlineOK, &r);
  192.  
  193.     GetDItem (dp, percentItem, &itemType, &percentText, &r);
  194.  
  195.     NumToString (((PParameters) *gStuff->parameters)->percent, s);
  196.     SetIText (percentText, s);
  197.  
  198.     do
  199.         {
  200.         SelIText (dp, percentItem, 0, 32767);
  201.  
  202.         ModalDialog (nil, &item);
  203.  
  204.         if (item == OK)
  205.             {
  206.             GetIText (percentText, s);
  207.  
  208.             StringToNum (s, &x);
  209.  
  210.             if (x < 1 || x > 99)
  211.                 item = 0;
  212.  
  213.             for (j = 1; j <= Length (s); j++)
  214.                 if (s[j] < '0' || s[j] > '9')
  215.                     item = 0;
  216.  
  217.             if (item == 0)
  218.                 SysBeep (1);
  219.             }
  220.         }
  221.     while (item != OK && item != Cancel);
  222.  
  223.     DisposDialog (dp);
  224.     HPurge ((Handle) dt);
  225.  
  226.     if (item == Cancel)
  227.         {
  228.         gResult = 1;
  229.         return;
  230.         }
  231.  
  232.     ((PParameters) *gStuff->parameters)->percent = x;
  233.     }
  234.  
  235. #undef dialogID
  236. #undef hookItem
  237. #undef percentItem
  238.  
  239. /*****************************************************************************/
  240.  
  241. /* Prepare to filter an image.    If the plug-in filter needs a large amount
  242.    of buffer memory, this routine should set the bufferSpace field to the
  243.    number of bytes required. */
  244.  
  245. void DoPrepare (void)
  246.  
  247.     {
  248.     }
  249.  
  250. /*****************************************************************************/
  251.  
  252. /* Requests pointer to the first part of the image to be filtered. */
  253.  
  254. void DoStart (void)
  255.  
  256.     {
  257.     gStuff->inRect          = gStuff->filterRect;
  258.     gStuff->inRect.bottom = gStuff->inRect.top + 1;
  259.  
  260.     gStuff->inLoPlane = 0;
  261.     gStuff->inHiPlane = gStuff->planes - 1;
  262.  
  263.     gStuff->outRect = gStuff->inRect;
  264.  
  265.     gStuff->outLoPlane = 0;
  266.     gStuff->outHiPlane = gStuff->planes - 1;
  267.     }
  268.  
  269. /*****************************************************************************/
  270.  
  271. /* Filters the area and requests the next area. */
  272.  
  273. void DoContinue (void)
  274.  
  275.     {
  276.     short rand;
  277.     short count;
  278.     short plane;
  279.     short percent;
  280.     unsigned char r;
  281.     unsigned char g;
  282.     unsigned char b;
  283.     unsigned char *srcPtr;
  284.     unsigned char *dstPtr;
  285.  
  286.     if (TestAbort ())
  287.         {
  288.         gResult = 1;
  289.         return;
  290.         }
  291.  
  292.     UpdateProgress ((long) gStuff->inRect.top - gStuff->filterRect.top,
  293.                     (long) gStuff->filterRect.bottom - gStuff->filterRect.top);
  294.  
  295.     percent = ((PParameters) *gStuff->parameters)->percent;
  296.  
  297.     r = gStuff->background.red     >> 8;
  298.     g = gStuff->background.green >> 8;
  299.     b = gStuff->background.blue  >> 8;
  300.  
  301.     srcPtr = (unsigned char *) gStuff->inData;
  302.     dstPtr = (unsigned char *) gStuff->outData;
  303.  
  304.     count = gStuff->filterRect.right - gStuff->filterRect.left;
  305.     
  306.     while (count--)
  307.         {
  308.  
  309.         rand = Random ();
  310.         rand = (rand < 0 ? -rand : rand);
  311.  
  312.         if (rand % 100 < percent)
  313.             if (gStuff->planes == 3)
  314.                 {
  315.                 *(dstPtr++) = r;
  316.                 *(dstPtr++) = g;
  317.                 *(dstPtr++) = b;
  318.                 srcPtr += 3;
  319.                 }
  320.             else
  321.                 {
  322.                 *(dstPtr++) = r;
  323.                 srcPtr++;
  324.                 }
  325.         else
  326.             for (plane = 0; plane < gStuff->planes; plane++)
  327.                 *(dstPtr++) = *(srcPtr++);
  328.  
  329.         }
  330.         
  331.     gStuff->inRect.top      = gStuff->inRect.top      + 1;
  332.     gStuff->inRect.bottom = gStuff->inRect.bottom + 1;
  333.  
  334.     if (gStuff->inRect.top >= gStuff->filterRect.bottom)
  335.         SetRect (&gStuff->inRect, 0, 0, 0, 0);
  336.  
  337.     gStuff->outRect = gStuff->inRect;
  338.     }
  339.  
  340. /*****************************************************************************/
  341.  
  342. /* This routine will always be called if DoStart does not return an error
  343.    (even if DoContinue returns an error or the user aborts the operation).
  344.    This allows the module to perform any needed cleanup.  None is required
  345.    in this example. */
  346.  
  347. void DoFinish (void)
  348.  
  349.     {
  350.     }
  351.  
  352. /*****************************************************************************/
  353.  
  354. /* Main dispatching routine.  Initializes and sets up the global variables,
  355.    and performs the operation specified by the selector. */
  356.  
  357. pascal void main (selector, stuff, data, result)
  358.  
  359. short selector;
  360. FilterRecordPtr stuff;
  361. long *data;
  362. short *result;
  363.  
  364.     {
  365.  
  366.     /* Allow access to global variables */
  367.  
  368.     RememberA0 ();
  369.     SetUpA4 ();
  370.  
  371.     /* Copy the current quickdraw globals into the plug-in local copy */
  372.  
  373.     asm
  374.         {
  375.             MOVE.L    (A5),A0         ; Get address of real quickdraw globals
  376.             SUB.L    #126,A0         ; Move to start
  377.             LEA     randSeed,A1     ; Get address of local copy
  378.             MOVE.W    #64,D0            ; Globals are 65 words long
  379.         @1    MOVE.W    (A0)+,(A1)+     ; Copy a word
  380.             DBF     D0,@1            ; Move to next word
  381.         }
  382.  
  383.     /* Perform the requested operation */
  384.  
  385.     gStuff    = stuff;
  386.     gResult = noErr;
  387.  
  388.     switch (selector)
  389.         {
  390.  
  391.         case filterSelectorAbout:
  392.             DoAbout ();
  393.             break;
  394.  
  395.         case filterSelectorParameters:
  396.             DoParameters ();
  397.             break;
  398.  
  399.         case filterSelectorPrepare:
  400.             DoPrepare ();
  401.             break;
  402.  
  403.         case filterSelectorStart:
  404.             DoStart ();
  405.             break;
  406.  
  407.         case filterSelectorContinue:
  408.             DoContinue ();
  409.             break;
  410.  
  411.         case filterSelectorFinish:
  412.             DoFinish ();
  413.             break;
  414.  
  415.         default:
  416.             gResult = filterBadParameters;
  417.  
  418.         }
  419.  
  420.     *result = gResult;
  421.  
  422.     /* Restore the application's A4 register */
  423.  
  424.     RestoreA4 ();
  425.  
  426.     }
  427.